home *** CD-ROM | disk | FTP | other *** search
- #include <stdio.h>
- #include <string.h>
- #include <ctype.h>
- #include <stdlib.h>
- #include <limits.h>
- #include <netdb.h>
- #include <net/if.h>
- #include "netconf.h"
- #include "internal.h"
- #include "../misc/misc.h"
- #include "../xconf/xconf.h"
- #include "netconf.m"
-
-
- /* #Specification: devices / management
- netconf knows how to load a devices module (probing) and how
- to configure it (ifconfig). It also knows how to update the
- different routes.
- */
- #
-
- /*
- Programme a network interface (ifconfig) only if needed,
-
- Compare the current configuration with the expected configuration.
- If there is a mismatch (or the interface is not configure), then
- it is reconfigure with the expected values.
-
- Return -1 if any error.
- */
- static int devices_ifconfig(
- const char *device,
- const char *expected_hst,
- const char *expected_msk)
- {
- IFCONFIG_INFO info;
- int ret = ifconfig_getinfo (device,info);
- if (ret == -1){
- xconf_error (MSG_U(E_CANTPROBE
- ,"Can't probe current setup of network device %s\n"
- "No way to activate the network\n")
- ,device);
- }else{
- DAEMON *dae = daemon_find ("ifconfig");
- if (dae != NULL){
- if (strcmp(info.ip_addr,expected_hst)==0
- && strcmp(info.netmask,expected_msk)==0
- && info.flags & IFF_UP){
- ret = 0;
- }else{
- char cmd[300];
- /* #Specification: netconf / ifconfig / down
- We always force an interface DOWN
- before reconfiguring it. It has
- the side effect of cleaning the route
- table for that device.
- */
- sprintf (cmd,"%s down",device);
- netconf_system_if ("ifconfig",cmd);
- sprintf (cmd,"%s %s netmask %s",device,expected_hst
- ,expected_msk);
- ret = netconf_system_if ("ifconfig",cmd);
- }
- }
- }
- return ret;
- }
- /*
- Configure the loopback device.
- Return -1 if any error.
- */
- int netconf_setloopback()
- {
- /* #Specification: loopback / strategy
- As far as I know, there is only a way to configure the
- loopback device.
-
- /sbin/ifconfig lo 127.0.0.1
- /sbin/route add -net loopback
- */
- int ret = devices_ifconfig ("lo","127.0.0.1","255.0.0.0");
- if (ret == 0){
- char gateway[PATH_MAX];
- if (!route_isactive("127.0.0.0",gateway)){
- ret = netconf_system_if ("route","add -net 127.0.0.0 lo");
- }
- }
- return ret == 0 ? 0 : -1;
- }
- /*
- Format in text the major IP number of a HOST
- */
- void devices_ip2a(struct hostent *ent, char *buf)
- {
- unsigned char *numadr = (unsigned char *)ent->h_addr_list[0];
- char *pt = buf;
- int len = ent->h_length;
- for (int i=0; i<len; i++){
- pt += sprintf (pt,i==0 ? "%d":".%d",numadr[i]);
- }
- }
- void devices_ip2a(struct hostent *ent, SSTRING &ip)
- {
- char buf[16];
- devices_ip2a (ent,buf);
- ip.setfrom (buf);
- }
- /*
- Format in text an IP number
- */
- void devices_ip2a(unsigned long ip, char *buf)
- {
- union{
- long num;
- unsigned char car[4];
- }u;
- u.num = ip;
- sprintf (buf,"%d.%d.%d.%d",u.car[3],u.car[2],u.car[1],u.car[0]);
- }
- /*
- Format in text the major IP number of a NET
- */
- void devices_ip2a(struct netent *ent, char *buf)
- {
- devices_ip2a (ent->n_net,buf);
- }
- void devices_ip2a(struct netent *ent, SSTRING &ip)
- {
- char buf[16];
- devices_ip2a (ent->n_net,buf);
- ip.setfrom (buf);
- }
-
- /*
- Translate an IP number (ascii) into four number
- Return -1 if the IP number is invalid.
- */
- int device_aip24 (const char *aip, int num4[4])
- {
- int ret = 0;
- for (int i=0; i<4; i++){
- if (!isdigit(aip[0])){
- ret = -1;
- break;
- }else{
- int no = num4[i] = atoi(aip);
- if (no < 0 || no > 255) ret = -1;
- while (isdigit(*aip)) aip++;
- if (i < 3 && *aip != '.'){
- ret = -1;
- break;
- }
- aip++;
- }
- }
- return ret;
- }
-
-
- /*
- Check is a string is valid IP number.
- if (ishost), check if the IP is not a broadcast or a network address.
- */
- bool device_validip(const char *aip, bool ishost)
- {
- int num4[4];
- bool ret = false;
- if (device_aip24(aip,num4) != -1){
- ret = true;
- if (ishost && (num4[3] == 0 || num4[3] == 255)){
- ret = false;
- }
- }
- return ret;
- }
- #if 0
- /*
- Perform a gethostbyname with error reporting.
- Return -1 if not found.
- */
- static int devices_gethostbyname(
- const char *host,
- const char *device,
- char *ip_num, // Will contain the formatted IP address
- int silent) // Ok if not set, no error message
- {
- struct hostent *ent = gethostbyname(host);
- int ret = -1;
- if (ent == NULL){
- if (!silent){
- xconf_error ("%s is not defined\n"
- "Can't configured device %s\n",host,device);
- }
- }else{
- ret = 0;
- devices_ip2a (ent,ip_num);
- }
- return ret;
- }
- /*
- Perform a getnetbyname with error reporting.
- Return -1 if not found.
- */
- static int devices_getnetbyname(
- const char *net,
- const char *device,
- char *ip_num, // Will contain the formatted IP address
- int silent) // Ok if not set, no error message
- {
- struct netent *ent = getnetbyname(net);
- int ret = -1;
- if (ent == NULL){
- if (!silent){
- xconf_error ("%s is not defined\n"
- "Can't configured device %s\n",net,device);
- }
- }else{
- ret = 0;
- devices_ip2a (ent,ip_num);
- }
- return ret;
- }
- #endif
- struct IFACE_NUMS{
- char hst[20];
- char net[20];
- char msk[20];
- };
-
- void device_setstdnetmask(
- const char *hostip, // IP number of a HOST
- char *def_net, // Default network number
- char *def_msk) // Default netmask
- {
- int num4[4];
- device_aip24 (hostip,num4);
- if (num4[0] == 0){
- strcpy (def_net,"0.0.0.0");
- strcpy (def_msk,"0.0.0.0");
- }else if (num4[0] <= 127){
- sprintf (def_net,"%d.0.0.0",num4[0]);
- strcpy (def_msk,"255.0.0.0");
- }else if (num4[0] <= 191){
- sprintf (def_net,"%d.%d.0.0"
- ,num4[0],num4[1]);
- strcpy (def_msk,"255.255.0.0");
- }else{
- sprintf (def_net,"%d.%d.%d.0"
- ,num4[0],num4[1],num4[2]);
- strcpy (def_msk,"255.255.255.0");
- }
- }
-
- static int device_copystr (char *dst, SSTRING &src)
- {
- src.copy (dst);
- return src.is_empty() ? -1 : 0;
- }
- /*
- Get the IP number assigned to an interface (host,network and mask)
- Fill default values if some information is not fully specified.
- Return -1 if to much is missing.
- */
- static int device_ifaceinfo (
- const char *device, // Name of the device (for error report)
- INTER_INFO &itf,
- IFACE_NUMS &nums)
- {
- int ret = -1;
- int h_ok = device_copystr (nums.hst,itf.ipaddr);
- int n_ok = device_copystr (nums.net,itf.network);
- int m_ok = device_copystr (nums.msk,itf.netmask);
- if (h_ok != -1){
- /* #Specification: ifconfig / eth devices / 127.0.0.1
- Linuxconf won't configure an ethernet
- interface to 127.0.0.1. It will simply ignore it.
-
- This case happen when a properly configured
- linux system without an ethernet adaptor get
- one.
- */
- if (strcmp(nums.hst,"127.0.0.1")!=0){
- /* #Specification: ifconfig / netmask and network / optionnal
- The netmask and network address of a network specification are
- optionnal. The kernel (or ifconfig or route, I don't know)
- compute suitable defaults.
- */
- char def_net[20];
- char def_msk[20];
- device_setstdnetmask(nums.hst,def_net,def_msk);
- if (n_ok == -1) strcpy (nums.net,def_net);
- if (m_ok == -1) strcpy (nums.msk,def_msk);
- ret = 0;
- if (!device_validip(nums.hst,true)
- || !device_validip(nums.net,false)
- || !device_validip(nums.msk,false)){
- ret = -1;
- xconf_error (
- "Invalid IP number for interface %s"
- ,device);
- }
- }
- }
- return ret;
- }
-
- /*
- Load a network device module.
- Return -1 if any error
- */
- int device_insmod (const char *devname)
- {
- return netconf_system_if ("modprobe",devname);
- }
-
-
-
-
- /*
- Initialise a network device and set the basic route to it.
- */
- static int device_set (
- int dev_exist, // Is the device configured in the kernel ?
- const char *device, // Name of the device
- INTER_INFO &itf)
- {
- int ret = -1;
- IFACE_NUMS nums;
- int ip_needed = device_ifaceinfo (device,itf,nums) != -1;
- if (ip_needed){
- /* #Specification: netconf / devices / modules
- If a device (eth?) is not available in the kernel
- linuxconf does a "modprobe device" to load the module.
- */
- if (!dev_exist) dev_exist = device_insmod (device) != -1;
- if (dev_exist){
- if (ip_needed){
- ret = devices_ifconfig(device,nums.hst,nums.msk);
- if (ret == 0){
- char cmd[300];
- char gateway[PATH_MAX];
- int status = route_isactive(nums.net,gateway);
- if (status && strcmp(gateway,device)!=0){
- sprintf (cmd,"del -net %s",nums.net);
- ret = netconf_system_if ("route",cmd);
- status = 0;
- }
- if (!status){
- sprintf (cmd,"add -net %s %s",nums.net,device);
- ret = netconf_system_if ("route",cmd);
- }
- }
- }
- }else{
- xconf_error (MSG_U(E_NODEVICE
- ,"Networking was configured\n"
- "for the interface %s\n"
- "but this device is not configured\n"
- "in the kernel\n")
- ,device);
- }
- }else if (!dev_exist){
- // No configuration (IP or IPX) for this device
- // but it is not there anyway
- ret = 0;
- }
- return ret;
- }
- const char *tb_netdevices[]={
- "eth0","eth1","eth2","eth3"
- };
- /*
- Configure the main communication devices (ethernet) and set the
- basic route.
-
- Return -1 if any error.
- */
- int netconf_setdevices()
- {
- /* #Specification: network devices / lookup
- netconf finds out which permanent network devices do exist
- by reading /proc/net/dev. Slip devices are ignored because
- they are not managed properply by netconf right now.
-
- In fact, netconf deal only with ETHx devices.
- */
- int ret = 0;
- HOSTINFO info;
- if (netconf_loadinfos(info) != -1){
- for (int i=0; i<NB_ETH; i++){
- const char *devname = tb_netdevices[i];
- ret |= device_set (devlist_devexist(devname)
- ,devname
- ,info.a[i]);
- }
- }
- return ret;
- }
-
-
-
-
-